package com.geekbang.cn;

import org.eclipse.microprofile.config.spi.ConfigSource;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

public class HttpServletAttributeConfigSource implements ConfigSource, ServletRequestListener,ServletRequestAttributeListener {

    private ThreadLocal<Map<String,String>> httpServletRequestThreadLocal = new ThreadLocal<>();

    @Override
    public Set<String> getPropertyNames() {
        return httpServletRequestThreadLocal.get().keySet();
    }

    @Override
    public int getOrdinal() {
        return 600;
    }

    @Override
    public String getValue(String propertyName) {
        return httpServletRequestThreadLocal.get().get(propertyName);
    }

    @Override
    public String getName() {
        return "HttpServletAttributeConfigSource";
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        httpServletRequestThreadLocal.remove();
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        Map<String,String> map = new HashMap<>();
        ServletRequest servletRequest = sre.getServletRequest();
        Enumeration<String> enumeration = servletRequest.getAttributeNames();
        while(enumeration.hasMoreElements())
        {
            String attributeName = enumeration.nextElement();
            Object attributeValue = servletRequest.getAttribute(attributeName);
            map.put(attributeName,attributeValue==null?null:attributeValue.toString());
        }
    }

    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        Object attributeValue = servletRequestAttributeEvent.getValue();
        httpServletRequestThreadLocal.get().put(servletRequestAttributeEvent.getName(),attributeValue==null?null:attributeValue.toString());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        httpServletRequestThreadLocal.get().remove(servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        attributeAdded(servletRequestAttributeEvent);
    }
}
